package org.jeecg.modules.tls.rsmg.rsfile.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.tls.rsmg.rsfile.entity.RsFile;
import org.jeecg.modules.tls.rsmg.rsfile.mapper.RsFileMapper;
import org.jeecg.modules.tls.rsmg.rsfile.service.IRsFileService;
import org.jeecg.modules.tls.rsmg.rsfolder.entity.RsFolder;
import org.jeecg.modules.tls.rsmg.rsfolder.mapper.RsFolderMapper;
import org.jeecg.modules.tls.rsmg.rsfolder.service.IRsFolderService;
import org.jeecg.modules.tls.rsmg.utils.OssUtil;
import org.jeecg.modules.tls.rsmg.viewmodel.FileAndFolderListVM;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Description: rs_file
 * @Author: jeecg-boot
 * @Date:   2022-07-23
 * @Version: V1.0
 */
@Service
public class RsFileServiceImpl extends ServiceImpl<RsFileMapper, RsFile> implements IRsFileService {
    @Autowired
    RsFileMapper rsFileMapper;
    @Autowired
    IRsFolderService iRsFolderService;
    @Autowired
    RsFolderMapper rsFolderMapper;


    String endpoint = OssUtil.endpoint;
    String accessKeyId = OssUtil.keyid;
    String accessKeySecret = OssUtil.keysecret;
    String bucketName = OssUtil.bucketName;


    @Override
    public Boolean uploadFile(MultipartFile file, String folderId,String userId,String remark) {
        //获取文件名
        String originalFilename  = file.getOriginalFilename();
        //获取文件类型
        String fileType = file.getContentType();
        //获取文件大小和单位
        long size = file.getSize();
        Map<String,Object> fileSizeAndUnit = getFileSize(size);
        double fileSize = (double) fileSizeAndUnit.get("size");
        String unit = (String) fileSizeAndUnit.get("unit");
        // 如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
        String filePath=iRsFolderService.getPathById(folderId) + originalFilename;

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            InputStream inputStream =file.getInputStream();
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filePath,inputStream);
            // 上传文件。
            ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            return false;
        } catch (ClientException ce) {
            return false;
        } catch (IOException e) {
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        RsFile rsFile = new RsFile();
        rsFile.setName(originalFilename);
        rsFile.setType(fileType);
        rsFile.setPath("https://pai-xue-yuan.oss-cn-shenzhen.aliyuncs.com/"+filePath);
        rsFile.setUserId(userId);
        rsFile.setSize(fileSize);
        rsFile.setUnit(unit);
        rsFile.setRemark(remark);
        rsFile.setFolderId(folderId);
        rsFileMapper.insert(rsFile);
        return true;
    }

    @Override
    public Boolean deleteFile(String id) {
        RsFile rsFile = rsFileMapper.selectById(id);

        String objectName = iRsFolderService.getPathById(rsFile.getFolderId()) + rsFile.getName();

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 删除文件或目录。如果要删除目录，目录必须为空。

            ossClient.deleteObject(bucketName,objectName);

        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
            return false;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        rsFileMapper.deleteById(id);

        return true;
    }

    @Override
    public Boolean reNameFile(String id, String newName) {
        RsFile rsFile = rsFileMapper.selectById(id);
        String oldName = rsFile.getName();
        String suffix =  oldName.substring(oldName.lastIndexOf(".")+1);
        String sourceKey = iRsFolderService.getPathById(rsFile.getFolderId()) + oldName;
        String destinationKey = iRsFolderService.getPathById(rsFile.getFolderId()) + newName + "." + suffix;

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 将examplebucket下的srcobject.txt拷贝至同一Bucket下的destobject.txt。
            ossClient.copyObject(bucketName, sourceKey, bucketName, destinationKey);

            // 删除srcobject.txt。
            ossClient.deleteObject(bucketName, sourceKey);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
            return false;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        RsFile rsFile1 = new RsFile();
        rsFile1.setId(id);
        rsFile1.setName(newName+"."+suffix);
        rsFile1.setPath("https://pai-xue-yuan.oss-cn-shenzhen.aliyuncs.com/"+destinationKey);
        rsFileMapper.updateById(rsFile1);
        return true;
    }

    @Override
    public List<RsFile> getFileList(String folderId,String filetype,String name) {

        QueryWrapper<RsFile> queryWrapper = new QueryWrapper<>();
        if(name!=null&&!name.equals("null")){
            queryWrapper.like("name",name);
        }else {
            queryWrapper.eq("folder_id",folderId);
        }
        if(filetype!=null&&!filetype.equals("")&&!filetype.equals("null")){
            queryWrapper.eq("type",filetype);
        }

        return rsFileMapper.selectList(queryWrapper);
    }

    @Override
    public List<FileAndFolderListVM> getFileAndFolder(String id, String filetype, String name) {
        /*通过父ID查询当前文件夹下的子文件夹*/
        QueryWrapper<RsFolder> queryWrapper = new QueryWrapper<>();
        if(name!=null&&!name.equals("null")){
            /*用户是否搜索*/
            queryWrapper.like("name",name);
        }else{
            queryWrapper.eq("pid",id);
        }
        /*获取当前文件夹下的子文件夹*/
        List<RsFolder> rsFolderList = rsFolderMapper.selectList(queryWrapper);
        /*设置文件夹信息*/
        List<FileAndFolderListVM> fileAndFolderListVMList = rsFolderList.stream().map(i->{
            FileAndFolderListVM fileAndFolderListVM = new FileAndFolderListVM();
            fileAndFolderListVM.setId(i.getId());
            fileAndFolderListVM.setName(i.getName());
            fileAndFolderListVM.setSize("-----");
            fileAndFolderListVM.setPid(i.getPid());
            fileAndFolderListVM.setCreateTime(i.getCreateTime());
            fileAndFolderListVM.setType("folder");
            fileAndFolderListVM.setRemark(i.getRemark());
            fileAndFolderListVM.setUserName("admin");
            return fileAndFolderListVM;
        }).collect(Collectors.toList());

        /*获取该文件夹下的所有文件资源*/
        List<RsFile> rsFileList = getFileList(id,filetype,name);
        /*设置文件的详细信息*/
        DecimalFormat df = new DecimalFormat("#.00");
        for(RsFile rsFile : rsFileList){
            FileAndFolderListVM fileAndFolderListVM = new FileAndFolderListVM();
            fileAndFolderListVM.setId(rsFile.getId());
            fileAndFolderListVM.setPath(rsFile.getPath());
            fileAndFolderListVM.setSize(df.format(rsFile.getSize())+rsFile.getUnit());
            fileAndFolderListVM.setRemark(rsFile.getRemark());
            fileAndFolderListVM.setType(rsFile.getType());
            fileAndFolderListVM.setName(rsFile.getName());
            fileAndFolderListVM.setPid(rsFile.getFolderId());
            fileAndFolderListVM.setCreateTime(rsFile.getCreateTime());
            fileAndFolderListVM.setUserName("admin");
            fileAndFolderListVMList.add(fileAndFolderListVM);
        }
        /*返回*/
        return fileAndFolderListVMList;
    }

    @Override
    public String uploadImg(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String fileMainName = UUID.randomUUID().toString().replace("-", "");

        // 从原始文件名中获取文件扩展名
        String extensionName = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 使用目录、文件主体名称、文件扩展名称拼接得到对象名称
        String filePath = "resources/uploadImg" + "/" + fileMainName + extensionName;
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            InputStream inputStream =file.getInputStream();
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filePath,inputStream);
            // 上传文件。
            ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
            return null;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return null;
        } catch (IOException e) {
            return null;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        return "https://pai-xue-yuan.oss-cn-shenzhen.aliyuncs.com/"+filePath;
    }

    private Map<String,Object> getFileSize(long size){
        Map<String,Object> fileSizeAndUnit = new HashMap<>();
        double flagSize = size;
        if(flagSize<=100){
            fileSizeAndUnit.put("size",flagSize);
            fileSizeAndUnit.put("unit","B");
            return fileSizeAndUnit;
        }
        flagSize = flagSize/1024;
        if(flagSize<1024){
            fileSizeAndUnit.put("size",flagSize);
            fileSizeAndUnit.put("unit","KB");
            return fileSizeAndUnit;
        }
        flagSize = flagSize/1024;
        if(flagSize<1024){
            fileSizeAndUnit.put("size",flagSize);
            fileSizeAndUnit.put("unit","MB");
            return fileSizeAndUnit;
        }
        flagSize = flagSize/1024;
        fileSizeAndUnit.put("size",flagSize);
        fileSizeAndUnit.put("unit","GB");
        return fileSizeAndUnit;
    }
}
